package com.rc.evcharger.dto.terminal;


import com.rc.evcharger.common.annotation.ByteLength;
import com.rc.evcharger.common.terminal.RecordSource;
import com.rc.evcharger.common.terminal.Result;
import com.rc.evcharger.common.utils.DataUtil;
import com.rc.evcharger.common.utils.StringUtil;

import java.lang.reflect.Field;
import java.math.BigDecimal;

/**
 * 电桩充电时上报数据，返回数据项格式
 */
public class ChargeReportResult extends RecordSource implements Result {
    private Long pileId;

    @ByteLength(length = 1)
    private String gunNum; // 枪号 1：A枪 2：B枪
    @ByteLength(length = 15)
    private String orderNum; // 订单号;
    @ByteLength(length = 3, decimal = 2)
    private BigDecimal voltage;// 电压
    @ByteLength(length = 3, decimal = 2)
    private BigDecimal elec; // 电流
    @ByteLength(length = 4, decimal = 2)
    private BigDecimal power; // 电量；
    @ByteLength(length = 1)
    private BigDecimal soc; // 电量百分比；
    @ByteLength(length = 17)
    private String svin; // vin码；
    @ByteLength(length = 3, decimal = 2)
    private BigDecimal maxElec; // 允许最大电流；
    @ByteLength(length = 3, decimal = 2)
    private BigDecimal maxVoltage; // 允许最大电压；
    @ByteLength(length = 3, decimal = 2)
    private BigDecimal temperatureHigh; // 当前最高单体温度；
    @ByteLength(length = 3, decimal = 2)
    private BigDecimal temperatureLow; // 当前最低单体温度；
    @ByteLength(length = 3, decimal = 2)
    private BigDecimal demandVoltage; // 当前需求电压；
    @ByteLength(length = 3, decimal = 2)
    private BigDecimal demandElec; // 当前需求电流；
    @ByteLength(length = 4)
    private String obligate; // 预留字段;

    public ChargeReportResult() {
        super();
    }

    public ChargeReportResult(String source) {
        super();
        this.source = source;
    }

    /**
     * 遍历所有字段，按顺序和长度截取数据
     * @param str    数据域
     * @param source 硬件产商
     */
    public ChargeReportResult(String str, String source) {
        try {
            Field[] fields = this.getClass().getDeclaredFields();
            for (int i = 0; i < fields.length; i++) {
                ByteLength bl = fields[i].getAnnotation(ByteLength.class);
                if (bl == null) {
                    continue;
                }
                int len = bl.length() * 2 + bl.length() - 1;
                String value = str.substring(0, len);
                if (str.length() > len)
                    str = str.substring(len + 1);
                setValue(fields[i], bl, value);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public Long getPileId() {
        return pileId;
    }

    public void setPileId(Long pileId) {
        this.pileId = pileId;
    }

    public String getGunNum() {
        return gunNum;
    }

    public void setGunNum(String gunNum) {
        this.gunNum = gunNum;
    }

    public String getOrderNum() {
        return orderNum;
    }

    public void setOrderNum(String orderNum) {
        this.orderNum = orderNum;
    }

    public BigDecimal getVoltage() {
        return voltage;
    }

    public void setVoltage(BigDecimal voltage) {
        this.voltage = voltage;
    }

    public BigDecimal getElec() {
        return elec;
    }

    public void setElec(BigDecimal elec) {
        this.elec = elec;
    }

    public BigDecimal getPower() {
        return power;
    }

    public void setPower(BigDecimal power) {
        this.power = power;
    }

    public BigDecimal getSoc() {
        return soc;
    }

    public void setSoc(BigDecimal soc) {
        this.soc = soc;
    }

    public String getSvin() {
        return svin;
    }

    public void setSvin(String svin) {
        this.svin = svin;
    }

    public String getObligate() {
        return obligate;
    }

    public void setObligate(String obligate) {
        this.obligate = obligate;
    }

    public BigDecimal getMaxElec() {
        return maxElec;
    }

    public void setMaxElec(BigDecimal maxElec) {
        this.maxElec = maxElec;
    }

    public BigDecimal getMaxVoltage() {
        return maxVoltage;
    }

    public void setMaxVoltage(BigDecimal maxVoltage) {
        this.maxVoltage = maxVoltage;
    }

    public BigDecimal getTemperatureHigh() {
        return temperatureHigh;
    }

    public void setTemperatureHigh(BigDecimal temperatureHigh) {
        this.temperatureHigh = temperatureHigh;
    }

    public BigDecimal getTemperatureLow() {
        return temperatureLow;
    }

    public void setTemperatureLow(BigDecimal temperatureLow) {
        this.temperatureLow = temperatureLow;
    }

    public BigDecimal getDemandVoltage() {
        return demandVoltage;
    }

    public void setDemandVoltage(BigDecimal demandVoltage) {
        this.demandVoltage = demandVoltage;
    }

    public BigDecimal getDemandElec() {
        return demandElec;
    }

    public void setDemandElec(BigDecimal demandElec) {
        this.demandElec = demandElec;
    }

    @Override
    public ChargeReportResult getResult(String dataStr) {
        ChargeReportResult crr = new ChargeReportResult(dataStr, this.source);
        return crr;
    }

    private void setValue(Field field, ByteLength bl, String value) {
        try {
            if (field.getType().equals(BigDecimal.class) && value.length() == 2) {
                field.set(this, DataUtil.getBDValue(value, bl.decimal(), true));
            } else if (field.getType().equals(BigDecimal.class)) {
                field.set(this, DataUtil.getBDValue(value, bl.decimal(), false));
            } else if ((field.getName().equals("orderNum"))) {
                String orderNum = StringUtil.getOrderNum(value);
                field.set(this, orderNum);
            } else if ((field.getName().equals("svin"))) {
                field.set(this, StringUtil.resolveVin(value));
            } else {
                field.set(this, value);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public String toString() {
        return "ChargeReportResult{" +
                "pileId=" + pileId +
                ", gunNum='" + gunNum + '\'' +
                ", orderNum='" + orderNum + '\'' +
                ", voltage=" + voltage +
                ", elec=" + elec +
                ", power=" + power +
                ", soc=" + soc +
                ", svin='" + svin + '\'' +
                ", maxElec=" + maxElec +
                ", maxVoltage=" + maxVoltage +
                ", temperatureHigh=" + temperatureHigh +
                ", temperatureLow=" + temperatureLow +
                ", demandVoltage=" + demandVoltage +
                ", demandElec=" + demandElec +
                ", obligate='" + obligate + '\'' +
                '}';
    }

    public static void main(String[] args) {
        String data = "01 10 01 19 00 14 01 19 10 29 16 55 30 12 34 00 50 05 01 50 05 01 50 05 01 00 50 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 50 05 02 50 05 02 05 40 00 00 00 00";
        ChargeReportResult chargeReportResult = new ChargeReportResult(data, "resouce");

        System.out.println(chargeReportResult.toString());
    }
}
